
from django.conf import settings
from django.contrib.auth import login, authenticate
from django.contrib.auth.views import logout
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View

from users.forms import RegisterForm, ForgetForm, LoginForm, ModifyPwdForm
from users.models import UserProfile
from utils import constant
from utils.secret import Secret
from utils.send_reset_pwd_mail import send_resetpwd_email


# 注册
class RegisterView(View):
    def get(self, request):

        register_form = RegisterForm()
        return render(request, 'register.html', {'register_form': register_form})

    def post(self, request):
        # 1、获取前端传递的表单数据
        data = request.POST
        # 2、验证表单数据
        register_form = RegisterForm(data)
        res = register_form.is_valid()  # 验证成功返回True，验证失败返回False

        if res:
            # 验证成功，则执行相应业务逻辑操作，这里就直接返回验证成功后的字段数据
            # 获取验证成功后的字段
            email = register_form.cleaned_data['email']
            pwd = register_form.cleaned_data['password']
            # form表单只是校验了email格式和密码长度.应当对密码再做正则校验,可是我太懒了
            # 创建 user,写入数据库
            try:
                user = UserProfile.objects.create_user(
                    username=email,
                    email=email,
                    password=pwd,
                )
            except:
                # 新建用户失败,说明邮箱已经存在
                register_form.add_error('email','邮箱已存在')
                return render(request, 'register.html', {'register_form': register_form})

            # 登陆login,状态保持
            login(request, user)
            # 响应注册结果
            # 返回主页视图
            cur_response = redirect(reverse('index'))
            cur_response.set_cookie('username', email, max_age=constant.MAX_COOKIE_AGE)
            return cur_response
        # 验证失败，则在注册模板中通过register_form.errors获取错误
        return render(request, 'register.html', {'register_form': register_form})


# 登陆
class LoginView(View):
    def get(self, request):
        loginform = LoginForm()
        return render(request, 'login.html', {'loginform': loginform})

    def post(self, request):
        next = request.GET.get('next')
        data = request.POST
        login_form = LoginForm(data)
        if not login_form.is_valid():
            login_form.add_error('username', '用户名或密码错误')
            return render(request, 'login.html', {'login_form': login_form})

        username = login_form.cleaned_data['username']
        password = login_form.cleaned_data['password']
        try:
            user = authenticate(request, username=username, password=password)
        except:
            login_form.add_error('username', '用户名或密码错误')
            return render(request, 'login.html', {'login_form': login_form})

        if not user:
            login_form.add_error('username', '用户名或密码错误')
            return render(request, 'login.html', {'login_form': login_form})
        login(request, user)
        cur_response = redirect(next if next else reverse('index'))
        cur_response.set_cookie('username', username, max_age=constant.MAX_COOKIE_AGE)
        return cur_response


# 登出
class LogoutView(View):
    def get(self, request):
        cur_response = logout(request, next_page=reverse('index'))
        cur_response.delete_cookie('username')
        return cur_response


# 忘记密码
class ForgetPwdView(View):
    def get(self, request):
        forget_form = ForgetForm()
        return render(request, 'forgetpwd.html', {'forget_form': forget_form})

    def post(self, request):
        data = request.POST
        forget_form = ForgetForm(data)
        if forget_form.is_valid():
            email = forget_form.cleaned_data['email']
            try:
                user = UserProfile.objects.get(username=email)
            except:
                forget_form.add_error('email', '用户不存在')
                return render(request, 'forgetpwd.html', {'forget_form': forget_form})

            # 发送邮件
            reset_url = settings.EMAIL_RESET_URL + Secret().dumps(email) + '/'
            send_resetpwd_email(to_email=email, context=reset_url)
            return render(request, 'send_success.html')
        else:
            return render(request, 'forgetpwd.html', {'forget_form': forget_form})


# 重置密码
class ResetView(View):
    def get(self, request, active_code):

        try:
            email = Secret().loads(active_code)
            # print('email', type(email), email)
            UserProfile.objects.get(username=email)
        except:
            return render(request, 'active_fail.html')

        modify_form = ModifyPwdForm()
        return render(request, 'password_reset.html',
                      {'modify_form': modify_form, 'email': active_code})


# 修改密码
class ModifyPwd(View):
    def get(self, request):
        user = request.user
        if user.is_authenticated:
            modify_form = ModifyPwdForm()
            email_secret = Secret().dumps(user.username)
            return render(request, 'password_reset.html',
                          {'modify_form': modify_form, 'email': email_secret})
        else:
            return redirect(reverse('login') + r'?next=/users/info/')

    def post(self, request):
        data = request.POST
        email_secret = data.get('email')
        modify_form = ModifyPwdForm(data)
        if modify_form.is_valid():
            try:
                email = Secret().loads(email_secret)
                new_pwd1 = modify_form.cleaned_data['password1']
                new_pwd2 = modify_form.cleaned_data['password2']
                modify_form.errors['password1'] = '两次密码不一致'
                assert new_pwd1 == new_pwd2
                modify_form.errors['password1'] = '用户不存在'
                user = UserProfile.objects.get(username=email)
                modify_form.errors['password1'] = '重置密码失败'
                user.set_password(new_pwd1)
                user.save()
                # 重置密码成功,重定向到登录页
                return redirect(reverse('login'))
            except:
                return render(request, 'password_reset.html',
                              {'modify_form': modify_form, 'email': email_secret})
        else:
            return render(request, 'password_reset.html',
                          {'modify_form': modify_form, 'email': email_secret})


